package multi_thread.advanced.blocking_queue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @author Cheng Jun
 * Description: 有锁、有界、阻塞式的线程安全队列
 * ArrayBlockingQueue 利用类名分析法。Array、Blocking、Queue,其中Queue 表示ArrayBlockingQueue 是一个队列，
 * 队列的实现方式通常有两种，一种是基于数组实现，一种是基于链表实现。Array 表示 ArrayBlockingQueue 队列是基于数组实现的。
 * Blocking 表示 ArrayBlockingQueue 队列是一个 阻塞队列。
 * 阻塞实现方式一般有两种，synchronized 和 reentrantLock，在 Concurrent包下，基本都是采用第二种机制。
 * 有阻塞的话，就有等待通知机制(基于 await / signal)
 * 内部没有采用读写分离，读取和写入不可同时进行（读写操作互斥）。因为 入列 和 出列 的系列方法都是用的同一把锁。
 * ArrayBlockingQueue supports an optional fairness policy.
 * Once created, the capacity cannot be changed.
 * @version 1.0
 * @date 2021/10/28 6:43
 * @see LinkedBlockingQueueExample
 */
public class ArrayBlockingQueueExample {

    public static void main(String[] args) {

        ArrayBlockingQueue<Integer> intABQueue = new ArrayBlockingQueue<>(2);
        intABQueue.add(1);
        intABQueue.offer(2);
        System.out.println(intABQueue);

        // 如果队列满了，就会抛出异常 IllegalStateException – if this queue is full 推荐使用
        // intABQueue.add(3);
        // 如果队列满了，存不进去，不会抛异常。不推荐使用
        // intABQueue.offer(3);

        try {
            // 阻塞 timeout 时间后，尝试入列。如果队列还是满的，那么入列失败
            intABQueue.offer(3,3, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // try {
        //     // put 方法会阻塞住线程
        //     intABQueue.put(3);
        // } catch (InterruptedException e) {
        //     e.printStackTrace();
        // }
        intABQueue.poll();
    }
}
